package com.so206.plugins.pay;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.so206.po.*;
import com.so206.po.ext.QrCodeResponse;
import com.so206.po.ext.QrResponse;
import com.so206.service.OrderService;
import com.so206.service.PayConfigService;
import com.so206.service.SettLementService;
import com.so206.service.WebConfigService;
import com.so206.utils.PayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * 支付宝处理相关
 */
@Component
public class AliPayFunction {

    private static final String openApi = "https://openapi.alipay.com/gateway.do";

    @Autowired
    private SettLementService settLementService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private PayConfigService payConfigService;

    @Autowired
    private WebConfigService webConfigService;

    /**
     * 支付宝 - 向个人用户转账
     */
    public Boolean changeMoneyToAccount(SystemSett sett, SystemUser user, String appid, String open_private_key, String alipay_public_key) {
        BigDecimal money = sett.getSettFinalMoney();
        SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd");
        AlipayClient alipayClient = new DefaultAlipayClient(openApi, appid, open_private_key, "json", "utf-8", alipay_public_key, "RSA2");
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        TreeMap<Object, Object> bie_con = new TreeMap<>();
        bie_con.put("out_biz_no", sett.getSid());
        bie_con.put("payee_type", "ALIPAY_LOGONID");
        bie_con.put("payee_account", user.getZspayid());
        bie_con.put("amount", String.valueOf(money));
        bie_con.put("payer_show_name", "转账:" + time.format(sett.getCreateTime()));
        bie_con.put("payee_real_name", user.getZsname());
        bie_con.put("remark", "转账:" + sett.getSid());
        request.setBizContent(JSON.toJSONString(bie_con));
        AlipayFundTransToaccountTransferResponse response;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return false;
        }
        if (response.getCode().equals("10000")) {
            sett.setSettError("SUCCESS");
            sett.setTranNo(response.getOrderId());
            sett.setStatus(2);
            sett.setOkTime(new Date());
            settLementService.updateSystemSett(sett);
            return true;
        } else {
            String subCode = response.getSubCode();
            sett.setSettError(PayUtils.getSettPayErrorDeitl(subCode));
            sett.setStatus(3);
            sett.setOkTime(new Date());
            sett.setTranNo("000");
            settLementService.updateSystemSett(sett);
            return false;
        }
    }

    /**
     * 支付宝 - 向个人用户转账
     */
    public Map changeMoneyToAccountMap(Map sett, String appid, String open_private_key, String alipay_public_key) {
        HashMap<Object, Object> map = new HashMap<>();
        BigDecimal money = new BigDecimal(String.valueOf(sett.get("final_money")));
        AlipayClient alipayClient = new DefaultAlipayClient(openApi, appid, open_private_key, "json", "utf-8", alipay_public_key, "RSA2");
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        TreeMap<Object, Object> bie_con = new TreeMap<>();
        bie_con.put("out_biz_no", sett.get("sid"));
        bie_con.put("payee_type", "ALIPAY_LOGONID");
        bie_con.put("payee_account", sett.get("pid"));
        bie_con.put("amount", String.valueOf(money));
        bie_con.put("payer_show_name", sett.get("title"));
        bie_con.put("payee_real_name", sett.get("pname"));
        bie_con.put("remark", sett.get("title"));
        request.setBizContent(JSON.toJSONString(bie_con));
        AlipayFundTransToaccountTransferResponse response;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return null;
        }
        if (response.getCode().equals("10000")) {
            map.put("error", "Success");
            map.put("status", 2);
            map.put("tran_no", response.getOrderId());
            return map;
        } else {
            String subCode = response.getSubCode();
            map.put("error", PayUtils.getSettPayErrorDeitl(subCode));
            map.put("status", 3);
            map.put("tran_no", "000");
            return map;
        }
    }

    /**
     * 支付宝退款
     */
    public Map refund(SystemOrder order, String appid, String open_private_key, String alipay_public_key) {
        HashMap<Object, Object> map = new HashMap<>();
        AlipayClient alipayClient = new DefaultAlipayClient(openApi, appid, open_private_key, "json", "utf-8", alipay_public_key, AlipayConstants.SIGN_TYPE_RSA2);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        TreeMap<Object, Object> bie_con = new TreeMap<>();
        bie_con.put("out_trade_no", order.getId());
        bie_con.put("trade_no", order.getTradeNo());
        bie_con.put("refund_amount", order.getPrice().subtract(order.getSaleMonney()));
        bie_con.put("refund_reason", "退款:" + order.getOutOrderId());
        request.setBizContent(JSON.toJSONString(bie_con));
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        String code = response.getCode();
        if (code == null) {
            map.put("code", -1);
            map.put("msg", "操作失败!");
        } else {
            if (code.equals("10000") && response.getMsg().equals("Success")) {
                order.setStatus(3);
                orderService.updateOrder(order);
                map.put("code", 0);
                map.put("msg", response.getMsg());
            } else {
                String msg = response.getSubMsg();
                map.put("msg", msg);
                map.put("code", -1);
            }
        }
        return map;
    }

    /**
     * 支付宝 - 电脑网站支付
     */
    public String pc_pay(SystemOrder order, String appid, String open_private_key, String alipay_public_key) {
        AlipayClient alipayClient = new DefaultAlipayClient(openApi, appid, open_private_key, "json", "utf-8", alipay_public_key, AlipayConstants.SIGN_TYPE_RSA2);
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        SystemPayConfig config1 = payConfigService.getPayConfig(1L);
        SystemWeb web = webConfigService.find_by_id(1L);
        alipayRequest.setReturnUrl(web.getHttpUrl() + "/payment/return_page");
        alipayRequest.setNotifyUrl(config1.getRetDomain() + "/payment/alipay_notify");
        HashMap<Object, Object> param = new HashMap<>();
        param.put("subject", order.getTitle());
        param.put("body", order.getContext());
        param.put("out_trade_no", order.getOutOrderId());
        param.put("total_amount", order.getPrice().subtract(order.getSaleMonney()));
        param.put("product_code", "FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizContent(JSON.toJSONString(param));
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return form;
    }

    /**
     * 支付宝 - 手机网站支付
     */
    public String wap_pay(SystemOrder order, String appid, String open_private_key, String alipay_public_key) {
        AlipayClient alipayClient = new DefaultAlipayClient(openApi, appid, open_private_key, "json",
                "utf-8", alipay_public_key, AlipayConstants.SIGN_TYPE_RSA2);
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        SystemPayConfig config1 = payConfigService.getPayConfig(1L);
        SystemWeb web = webConfigService.find_by_id(1L);
        alipayRequest.setReturnUrl(web.getHttpUrl() + "/payment/return_page");
        alipayRequest.setNotifyUrl(config1.getRetDomain() + "/payment/alipay_notify");
        HashMap<Object, Object> param = new HashMap<>();
        param.put("subject", order.getTitle());
        param.put("body", order.getContext());
        param.put("out_trade_no", order.getOutOrderId());
        param.put("total_amount", order.getPrice().subtract(order.getSaleMonney()));
        param.put("product_code", "FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizContent(JSON.toJSONString(param));
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return form;
    }

    /**
     * 支付宝 - 当面付
     */
    public QrCodeResponse code_pay(SystemOrder order, String appid, String open_private_key, String alipay_public_key) {
        AlipayClient alipayClient = new DefaultAlipayClient(openApi, appid, open_private_key, "json", "utf-8", alipay_public_key, AlipayConstants.SIGN_TYPE_RSA2);
        AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();
        SystemPayConfig config1 = payConfigService.getPayConfig(1L);
        alipayRequest.setNotifyUrl(config1.getRetDomain() + "/payment/alipay_notify");
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setTotalAmount(order.getPrice().subtract(order.getSaleMonney()).toString());
        model.setBody(order.getContext());
        model.setSubject(order.getTitle());
        model.setTimeoutExpress("5m");
        model.setOutTradeNo(order.getOutOrderId());
        alipayRequest.setBizModel(model);
        String form = "";
        try {
            form = alipayClient.execute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        QrResponse qrResponse = JSON.parseObject(form, QrResponse.class);
        return qrResponse.getAlipay_trade_precreate_response();
    }


}
